package com.ibpd.henuocms.common;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.SocketException;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.CopyStreamListener;
import org.jsoup.helper.StringUtil;
/**
 * ftp辅助工具类，用来实现连接FTP服务器，以及向FTP上传文件
 * @author MG 
 *
 */
public class FTPUtil {
	private FTPClient ftp;
	private Long transByte=0L;
	public static final String FTP_ADDRESS="ftp_address";
	public static final String FTP_PORT="ftp_port";
	public static final String FTP_USERNAME="ftp_userName";
	public static final String FTP_PASSWORD="ftp_password";
	public static final String FTP_DEFAULTWORKDIR="ftp_workdir";
	
	private String address="";
	private String port="";
	private String userName="";
	private String password="";
	private String workDir="";

	/**
	 * 
	 * @param path
	 *            上传到ftp服务器哪个路径下 ,也就是FTP最初的工作目录
	 * @param addr
	 *            地址
	 * @param port
	 *            端口号
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * @return
	 * @throws Exception
	 */
	private boolean connect(String path, String addr, int port,
			String username, String password) {
		if (checkFtpStatus())
			return true;
		boolean result = false;
		ftp = new FTPClient();
		int reply;
		ftp.setCopyStreamListener(new CopyStreamListener() {

			public void bytesTransferred(CopyStreamEvent arg0) {
//				System.out.println("total:" + arg0.getStreamSize() + " local:"
//						+ arg0.getTotalBytesTransferred());

			}

			public void bytesTransferred(long arg0, int arg1, long arg2) {
//				System.out.println(arg0 + " " + arg1 + " " + arg2);
				transByte=arg0;

			}

		});
		try {
			ftp.connect(addr, port);
			ftp.login(username, password);
			ftp.setControlEncoding("UTF-8");
			ftp.enterLocalPassiveMode();
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
			ftp.setFileTransferMode(FTPClient.STREAM_TRANSFER_MODE);
			reply = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			ftp.changeWorkingDirectory(path);
			result = true;
			return result;
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 上传文件到ftp服务器，文件可以是文件或文件夹
	 * 
	 * @param file
	 *            上传的文件或文件夹
	 * @throws Exception
	 */
	private void upload(File file) throws Exception {
		if (!checkFtpStatus())
			throw new Exception("FTPClient尚未连接或连接失效");
		if (file.isDirectory()) {
			ftp.makeDirectory(file.getName());
			ftp.changeWorkingDirectory(file.getName());
			String[] files = file.list();
			for (int i = 0; i < files.length; i++) {
				File file1 = new File(file.getPath() + File.separator + files[i]);
				if (file1.isDirectory()) {
					upload(file1);
					ftp.changeToParentDirectory();
				} else {
					File file2 = new File(file.getPath() + "\\" + files[i]);
					FileInputStream input = new FileInputStream(file2);
					Boolean r = ftp.storeFile(new String(file2.getName().getBytes(), "iso-8859-1"), input);
					System.out
							.println("=====文件上传:" + file2.getName() + ":" + r);
					input.close();
				}
			}
		} else {
			File file2 = new File(file.getPath());
			FileInputStream input = new FileInputStream(file2);
			Boolean r = ftp.storeFile(new String(file2.getName().getBytes(), "iso-8859-1"), input);
			System.out.println("=====文件上传:" + file2.getName() + ":" + r);
			input.close();
		}
	}

	private void closeFtpConnection() {
		if (!checkFtpStatus())
			return;
		try {
			if (ftp.isConnected()) {
				ftp.logout();
				ftp.disconnect();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private Boolean checkFtpStatus() {
		if (ftp == null)
			return false;
		if (ftp.isConnected())
			return true;
		else
			return false;
	}

	/**
	 * 列出服务器上文件和目录
	 * 
	 * @param regStr
	 *            --匹配的正则表达式
	 */
	private String[] listRemoteFiles(String regStr) {
		if (!checkFtpStatus())
			return null;
		try {
			return ftp.listNames(regStr);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 列出Ftp服务器上的所有文件和目录
	 */
	private String[] listRemoteAllFiles() {
		if (!checkFtpStatus())
			return null;
		try {
			return ftp.listNames();

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
//	public FTPUtil(){
//		address=IbpdCommon.getInterface().getPropertiesValue(FTPUtil.FTP_ADDRESS);
//		port=IbpdCommon.getInterface().getPropertiesValue(FTPUtil.FTP_PORT);
//		userName=IbpdCommon.getInterface().getPropertiesValue(FTPUtil.FTP_USERNAME);
//		password=IbpdCommon.getInterface().getPropertiesValue(FTPUtil.FTP_PASSWORD);
//		workDir=IbpdCommon.getInterface().getPropertiesValue(FTPUtil.FTP_DEFAULTWORKDIR);
//	}
	public FTPUtil(String address,String port,String userName,String password,String workDir){
		this.address=address;
		this.port=port;
		this.userName=userName;
		this.password=password;
		this.workDir=workDir;

	}
	/////////////////下面是外部调用的方法
	/**
	 * 连接到Ftp server
	 */
	public Boolean connectFtpServer() throws NumberFormatException, Exception{
		if(StringUtils.isBlank(address) || StringUtils.isBlank(port) || StringUtils.isBlank(userName) || StringUtils.isBlank(password) || workDir==null){
			throw new NullPointerException("FTP参数不足,请检查配置文件中关于FTP的配置信息");
		}
		return this.connect(workDir, address, Integer.valueOf(port), userName, password);
	}
	private void chanageWorkDir(String dir) throws Exception{
		if(checkFtpStatus()){
			ftp.changeWorkingDirectory("/");
				String[] fs=dir.split("/");
				for(String fd:fs){
					if(!StringUtil.isBlank(fd)){
						ftp.makeDirectory(fd);
						ftp.changeWorkingDirectory(fd);
					}
				}
//			ftp.changeWorkingDirectory(dir);
			System.out.println("===chanageWorkingDir:"+dir);
		}
	}
	public void uploadFiles(String currentWorkDir,String files) throws NumberFormatException{
		uploadFiles(currentWorkDir,new String[]{files});
	}
	/**
	 * 上传文件，上传之前不需要连接ftp server，直接调用就行
	 * @param currentWorkDir
	 * @param files
	 * @throws Exception
	 */
	public void uploadFiles(String currentWorkDir,String[] files) throws NumberFormatException{
		if(files==null)
			return;
		try {
			if(connectFtpServer()){
				chanageWorkDir(currentWorkDir);
				for(String f:files){
					File uf=new File(f);
					if(uf.exists()){
						this.upload(uf);
					}
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.closeFtpConnection();
	}
	/**
	 * 上传文件，上传之前不需要连接ftp server，直接调用就行
	 * @param fs
	 * @throws Exception
	 */
	public void uploadFiles(String currentWorkDir,File[] fs) throws Exception{
		if(fs==null || fs.length==0)
			return;
		if(connectFtpServer()){
			chanageWorkDir(currentWorkDir);
			for(File uf:fs){
				if(uf.exists()){
					this.upload(uf);
				}
			}
		}
		this.closeFtpConnection();
	}
	public void closeConnection(){
		this.closeFtpConnection();
	}
	/**
	 * 扩展方法 供外部调用
	 * @return
	 * @throws NumberFormatException
	 * @throws Exception
	 */
	public FTPClient getCurrentFTPClient() throws NumberFormatException, Exception{
		if(!checkFtpStatus()){
			this.connectFtpServer();
		}
		return ftp;
	}
	/**
	 * 获取新实例,该函数仅仅是为了方便调用
	 * @return
	 */
	public static FTPUtil getNewInterface(String address,String port,String userName,String password,String workDir){
		return new FTPUtil(address,port,userName,password,workDir);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
//		try {
//			FTPUtil ftp=FTPUtil.getNewInterface();
//			ftp.uploadFiles("/",new String[]{"D:\\apache-tomcat-6.0.39\\webapps\\henuoCMS\\sites\\ssgfwssc\\bk"});
//			System.out.println("上传完毕");
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		String s="/a/b/c/d/e/f/index.html";
		s=s.split("/a/b/c/d")[1];
		System.out.println(s.substring(0,s.lastIndexOf("/")));
	}

	/**
	 * 获取已经上传的字节数（单个文件）--未测试
	 * @return
	 */
	public Long getTransByte() {
		return transByte;
	}

}
